import business.*
import javafx.scene.input.KeyCode
import javafx.scene.input.KeyEvent
import model.*
import org.itheima.kotlin.game.core.Window
import java.io.File
import java.util.concurrent.CopyOnWriteArrayList

class GameWindow :
    Window(BaseConfig.GAME_TITLE, BaseConfig.GAME_ICON, BaseConfig.GAME_WINDOW_WIDTH, BaseConfig.GAME_WINDOW_HEIGHT) {

    // 线程不安全
//    private var views = arrayListOf<IView>()
    private var views = CopyOnWriteArrayList<IView>()

    private lateinit var tank: Tank

    override fun onCreate() {
        // 创建地图 读取地图信息
        val mapFile = File(javaClass.getResource("map/1.map").path)
        // 地图的每一行
        val lines = mapFile.readLines()
        var xIndex: Int = 0
        lines.forEach {
            val columns = it.toCharArray()
            var yIndex: Int = 0
            columns.forEach { column ->
                val x = yIndex * BaseConfig.GAME_UNIT
                val y = xIndex * BaseConfig.GAME_UNIT
                when (column) {
                    '砖' -> {
                        views.add(Wall(x, y))
                    }

                    '铁' -> {
                        views.add(Steel(x, y))
                    }

                    '草' -> {
                        views.add(Grass(x, y))
                    }

                    '水' -> {
                        views.add(Water(x, y))
                    }

                    '敌' -> {
                        views.add(Enemy(x, y))
                    }
                }
                yIndex++
            }
            xIndex++
        }

        tank = Tank(9 * BaseConfig.GAME_UNIT, 12 * BaseConfig.GAME_UNIT)
        views.add(tank)

        // 老家
        val camp = Camp(
            BaseConfig.GAME_WINDOW_WIDTH / 2 - BaseConfig.GAME_UNIT,
            BaseConfig.GAME_WINDOW_HEIGHT - BaseConfig.GAME_UNIT - 32
        )
        views.add(camp)

    }

    override fun onDisplay() {
        // 绘制view
        views.forEach {
            it.draw()
        }
//        println("${views.size}")
    }

    override fun onKeyPressed(event: KeyEvent) {
        when (event.code) {
            KeyCode.W, KeyCode.UP -> {
                tank.move(Direction.UP)
            }

            KeyCode.S, KeyCode.DOWN -> {
                tank.move(Direction.DOWN)
            }

            KeyCode.A, KeyCode.LEFT -> {
                tank.move(Direction.LEFT)
            }

            KeyCode.D, KeyCode.RIGHT -> {
                tank.move(Direction.RIGHT)
            }
            KeyCode.ENTER -> {
                val bullet = tank.shot()
                views.add(bullet)
            }
            else -> {
                // do nothing
            }
        }
    }

    override fun onRefresh() {
        // 解决碰撞物和移动物体的碰撞
        views.filter { it is Moveable }.forEach { move ->
            move as Moveable
            var badDirection: Direction? = null
            var collisionBlock: Blockable? = null
            views.filter { (it is Blockable) and (move != it) }.forEach blockTag@{ block ->
                block as Blockable
                val willCollision = move.willCollision(block)
                // 发生碰撞跳出此循环
                willCollision?.let {
                    badDirection = willCollision
                    collisionBlock = block
                    return@blockTag
                }
            }

            // 通知碰撞的方向和障碍物
            move.notifyCollision(badDirection, collisionBlock)
        }

        // 处理业务逻辑，飞行的子弹
        views.filter { it is AutoFlyable }.forEach {
            (it as AutoFlyable).autoFly()
        }

        // 处理页面元素的回收处理
        views.filter { it is Destroyable }.forEach {
            it as Destroyable
            if (it.isDestroy()) {
                views.remove(it)
                if (it is Camp) {
                    val showDestroy = it.showDestroy()
                    showDestroy?.let {
                        views.addAll(showDestroy)
                    }
                }
            }
        }

        // 处理子弹和障碍物的碰撞
        views.filter { it is Attackable }.forEach { attack ->
            attack as Attackable
            views.filter { (it is Sufferable) and (attack.owner != it) and (attack != it) }
                .forEach sufferTag@{ suffer ->
                    suffer as Sufferable
                    if (attack.isCollision(suffer)) {
                        attack.notifyAttack()
                        val notifySuffer = suffer.notifySuffer(attack)
                        notifySuffer?.let {
                            views.addAll(notifySuffer)
                        }
                        return@sufferTag
                    }

                }
        }

        // 处理自动射击物的处理
        views.filter { it is AutoShotable }.forEach {
            it as AutoShotable
            val autoShot = it.autoShot()
            autoShot?.let {
                views.add(autoShot)
            }
        }
    }
}